home *** CD-ROM | disk | FTP | other *** search
/ Skunkware 5 / Skunkware 5.iso / src / Tools / mpeg_stat-2.2 / parseblock.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-05-10  |  12.2 KB  |  505 lines

  1. /* MPEGSTAT - analyzing tool for MPEG-I video streams
  2.  * 
  3.  *
  4.  *  Copyright (c) 1995 The Regents of the University of California.
  5.  * All rights reserved.
  6.  *
  7.  * Technical University of Berlin, Germany, Dept. of Computer Science
  8.  * Tom Pfeifer - Multimedia systems project - pfeifer@fokus.gmd.de
  9.  *
  10.  * Jens Brettin, Harald Masche, Alexander Schulze, Dirk Schubert
  11.  *
  12.  * This program uses parts of the source code of the Berkeley MPEG player
  13.  *
  14.  * ---------------------------
  15.  *
  16.  * Copyright (c) 1993 Technical University of Berlin, Germany
  17.  *
  18.  * for the parts of the Berkeley player used:
  19.  *
  20.  * Copyright (c) 1992 The Regents of the University of California.
  21.  * All rights reserved.
  22.  *
  23.  * ---------------------------
  24.  *
  25.  * Permission to use, copy, modify, and distribute this software and its
  26.  * documentation for any purpose, without fee, and without written agreement is
  27.  * hereby granted, provided that the above copyright notices and the following
  28.  * two paragraphs appear in all copies of this software.
  29.  * 
  30.  * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA 
  31.  * or the Technical University of Berlin BE LIABLE TO ANY PARTY FOR
  32.  * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
  33.  * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF
  34.  * CALIFORNIA or the Technical University of Berlin HAS BEEN ADVISED OF THE 
  35.  * POSSIBILITY OF SUCH DAMAGE.
  36.  * 
  37.  * THE UNIVERSITY OF CALIFORNIA and the Technical University of Berlin 
  38.  * SPECIFICALLY DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
  39.  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  40.  * PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE 
  41.  * UNIVERSITY OF CALIFORNIA and the Technical University of Berlin HAVE NO 
  42.  * OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, 
  43.  * OR MODIFICATIONS.
  44.  */
  45. #define NO_SANITY_CHECKS
  46. #include <assert.h>
  47. #include "video.h"
  48. #include "proto.h"
  49. #include "decoders.h"
  50. #include "dither.h"
  51. #include "opts.h"
  52.  
  53. /* note the C routines in decoders.c are surpassed by macros on decoders.h */
  54. /* External declarations. */
  55.  
  56. extern int zigzag_direct[];
  57. extern BlockVals blks;
  58.  
  59. /* Macro for returning 1 if num is positive, -1 if negative, 0 if 0. */
  60.  
  61. #define Sign(num) ((num > 0) ? 1 : ((num == 0) ? 0 : -1))
  62.  
  63. /* Error handling code (used by decoder macros)  */
  64. extern char *errorLocation, *errorSpecifics;
  65.  
  66. /* DCT Collection string */
  67. extern char *dctSpecifics;
  68.  
  69.  
  70. /*
  71.  *--------------------------------------------------------------
  72.  *
  73.  * ParseReconBlock --
  74.  *
  75.  *    Parse values for block structure from bitstream.
  76.  *      n is an indication of the position of the block within
  77.  *      the macroblock (i.e. 0-5) and indicates the type of 
  78.  *      block (i.e. luminance or chrominance). Reconstructs
  79.  *      coefficients from values parsed and puts in 
  80.  *      block.dct_recon array in vid stream structure.
  81.  *      sparseFlag is set when the block contains only one
  82.  *      coeffictient and is used by the IDCT.
  83.  *
  84.  * Results:
  85.  *    
  86.  *
  87.  * Side effects:
  88.  *      Bit stream irreversibly parsed.
  89.  *
  90.  *--------------------------------------------------------------
  91.  */
  92.  
  93. #define DCT_recon blockPtr->dct_recon
  94. #define DCT_dc_y_past blockPtr->dct_dc_y_past
  95. #define DCT_dc_cr_past blockPtr->dct_dc_cr_past
  96. #define DCT_dc_cb_past blockPtr->dct_dc_cb_past
  97.  
  98. #define DeZigZag(pos,i) if ((i<64)&&(i>=0)) {pos=zigzag_direct[i];}\
  99.          else {                                                    \
  100.      sprintf(errorSpecifics,"\nIllegal value in block (%d %d)... skipping...\n",blks.frame,n);\
  101.          return SKIP_TO_START_CODE;}
  102. int
  103. ParseReconBlock(n)
  104.      int n;
  105. {
  106. #ifdef RISC
  107.   unsigned int temp_curBits;
  108.   int temp_bitOffset;
  109.   int temp_bufLength;
  110.   unsigned int *temp_bitBuffer;
  111. #endif
  112.   
  113.   Block *blockPtr = &curVidStream->block;
  114.   int coeffCount;
  115.   char scratch[100];
  116.   
  117.   if (bufLength < 150)
  118.     correct_underflow();
  119.   
  120. #ifdef RISC
  121.   temp_curBits = curBits;
  122.   temp_bitOffset = bitOffset;
  123.   temp_bufLength = bufLength;
  124.   temp_bitBuffer = bitBuffer;
  125. #endif
  126.   
  127.   if (opts&COLLECTING&DCT_INFO) {
  128.     /* Note the below assumes called in 0..5 order */
  129.     if (n==0) {
  130.       sprintf(dctSpecifics," 0: ");
  131.     } else {
  132.       sprintf(scratch,"%1d: ",n);
  133.       strcat(dctSpecifics, scratch);
  134.     }
  135.   }
  136.   {
  137.     /*
  138.      * Copy the globals curBits, bitOffset, bufLength, and bitBuffer
  139.      * into local variables with the same names, so the macros use the
  140.      * local variables instead.  This allows register allocation and
  141.      * can provide 1-2 fps speedup.  On machines with not so many registers,
  142.      * don't do this.
  143.      */
  144. #ifdef RISC
  145.     register unsigned int curBits = temp_curBits;
  146.     register int bitOffset = temp_bitOffset;
  147.     register int bufLength = temp_bufLength;
  148.     register unsigned int *bitBuffer = temp_bitBuffer;
  149. #endif
  150.     
  151.     int diff;
  152.     int size, level, i, run, pos, coeff;
  153.     short int *reconptr;
  154.     unsigned char *iqmatrixptr, *niqmatrixptr;
  155.     int qscale;
  156.     
  157.     reconptr = DCT_recon[0];
  158.     
  159.     /* 
  160.      * Hand coded version of memset that's a little faster...
  161.      * Old call:
  162.      *    memset((char *) DCT_recon, 0, 64*sizeof(short int));
  163.      */
  164.     {
  165.       INT32 *p;
  166.       p = (INT32 *) reconptr;
  167.       
  168.       p[0] = p[1] = p[2] = p[3] = p[4] = p[5] = p[6] = p[7] = p[8] = p[9] = 
  169.     p[10] = p[11] = p[12] = p[13] = p[14] = p[15] = p[16] = p[17] = p[18] =
  170.       p[19] = p[20] = p[21] = p[22] = p[23] = p[24] = p[25] = p[26] = p[27] =
  171.         p[28] = p[29] = p[30] = p[31] = 0;
  172.       
  173.     }
  174.     
  175.     if (curVidStream->mblock.mb_intra) {
  176.       
  177.       if (n < 4) {
  178.     
  179.     /*
  180.      * Get the luminance bits.  This code has been hand optimized to
  181.      * get by the normal bit parsing routines.  We get some speedup
  182.      * by grabbing the next 16 bits and parsing things locally.
  183.      * Thus, calls are translated as:
  184.      *
  185.      *    show_bitsX  <-->   next16bits >> (16-X)
  186.      *    get_bitsX   <-->   val = next16bits >> (16-flushed-X);
  187.      *               flushed += X;
  188.      *               next16bits &= bitMask[flushed];
  189.      *    flush_bitsX <-->   flushed += X;
  190.      *               next16bits &= bitMask[flushed];
  191.      *
  192.      * I've streamlined the code a lot, so that we don't have to mask
  193.      * out the low order bits and a few of the extra adds are removed.
  194.      *    bsmith
  195.      */
  196.     unsigned int next16bits, index, flushed;
  197.     
  198.     show_bits16(next16bits);
  199.     index = next16bits >> (16-7);
  200.     size = dct_dc_size_luminance[index].value;
  201.     flushed = dct_dc_size_luminance[index].num_bits;
  202.     next16bits &= bitMask[16+flushed];
  203.  
  204.     if (size != 0) {
  205.       flushed += size;
  206.       diff = next16bits >> (16-flushed);
  207.           if (!(diff & bitTest[32-size])) {
  208.         diff = rBitMask[size] | (diff + 1);
  209.       }
  210.     } else {
  211.       diff = 0;
  212.     }
  213.     flush_bits(flushed);
  214.  
  215.     if (n == 0) {
  216.       coeff = diff << 3;
  217.       if (curVidStream->mblock.mb_address -
  218.           curVidStream->mblock.past_intra_addr > 1) 
  219.         coeff += 1024;
  220.       else coeff += DCT_dc_y_past;
  221.       DCT_dc_y_past = coeff;
  222.     } else {
  223.       coeff = DCT_dc_y_past + (diff << 3);
  224.       DCT_dc_y_past = coeff;
  225.     }
  226.     if (opts&COLLECTING&DCT_INFO) {
  227.       sprintf(scratch, "(%d) ",coeff);
  228.       strcat(dctSpecifics,scratch);
  229.     }        
  230.       } else {
  231.     
  232.     /*
  233.      * Get the chrominance bits.  This code has been hand optimized
  234.      * as described above
  235.      */
  236.     unsigned int next16bits, index, flushed;
  237.  
  238.     show_bits16(next16bits);
  239.     index = next16bits >> (16-8);
  240.     size = dct_dc_size_chrominance[index].value;
  241.     flushed = dct_dc_size_chrominance[index].num_bits;
  242.     next16bits &= bitMask[16+flushed];
  243.     
  244.     if (size != 0) {
  245.       flushed += size;
  246.       diff = next16bits >> (16-flushed);
  247.           if (!(diff & bitTest[32-size])) {
  248.         diff = rBitMask[size] | (diff + 1);
  249.       }
  250.     } else {
  251.       diff = 0;
  252.     }
  253.     flush_bits(flushed);
  254.     
  255.     if (n == 4) {
  256.       coeff = diff << 3;
  257.       if (curVidStream->mblock.mb_address -
  258.           curVidStream->mblock.past_intra_addr > 1) 
  259.         coeff += 1024;
  260.       else coeff += DCT_dc_cr_past;
  261.       DCT_dc_cr_past = coeff;
  262.  
  263.     } else {
  264.       coeff = diff << 3;
  265.       if (curVidStream->mblock.mb_address -
  266.           curVidStream->mblock.past_intra_addr > 1) 
  267.         coeff += 1024;
  268.       else coeff += DCT_dc_cb_past;
  269.       DCT_dc_cb_past = coeff;
  270.     }
  271.  
  272.     if (opts&COLLECTING&DCT_INFO) {
  273.       sprintf(scratch, "(%d) ",coeff);
  274.       strcat(dctSpecifics,scratch);
  275.     }        
  276.       }
  277.       
  278.       *reconptr = coeff;
  279.       i = 0; pos = 0;
  280.       coeffCount = (coeff != 0);
  281.     
  282.       if (curVidStream->picture.code_type != 4) {
  283.     
  284.     qscale = curVidStream->slice.quant_scale;
  285.     iqmatrixptr = curVidStream->intra_quant_matrix[0];
  286.     
  287.     while (1) {
  288.  
  289.       DecodeDCTCoeffNext(run, level);
  290.  
  291.       if (run == END_OF_BLOCK) break;
  292.  
  293.       i = i + run + 1;
  294.  
  295.       DeZigZag(pos,i);
  296.  
  297.       if (opts&COLLECTING&DCT_INFO) {
  298.         sprintf(scratch, "%d %d, ",pos,level);
  299.         strcat(dctSpecifics,scratch);
  300.       }        
  301.       coeff = (level * qscale * ((int) iqmatrixptr[pos])) >> 3;
  302.       if (level < 0) {
  303.         coeff += (coeff & 1);
  304.       } else {
  305.         coeff -= (coeff & 1);
  306.       }
  307.       
  308.       reconptr[pos] = coeff;
  309.       
  310.       coeffCount++;/* Used to be if (coeff) {}, but didnt make sense */
  311.     }
  312.     
  313.     
  314.     {
  315.       extern unsigned int *mbCoeffPtr;
  316.       if (COLLECTING) mbCoeffPtr[pos]++;
  317.     }
  318.     
  319.     flush_bits(2);
  320.     
  321.     goto end;
  322.       }
  323.     } else {
  324.       
  325.       niqmatrixptr = curVidStream->non_intra_quant_matrix[0];
  326.       qscale = curVidStream->slice.quant_scale;
  327.       
  328.       DecodeDCTCoeffFirst(run, level);
  329.       i = run;
  330.       
  331.       DeZigZag(pos,i);
  332.       if (opts&COLLECTING&DCT_INFO) {
  333.     sprintf(scratch, "%d %d, ",pos,level);
  334.     strcat(dctSpecifics,scratch);
  335.       }        
  336.       if (level < 0) {
  337.     coeff = (((level<<1) - 1) * qscale * 
  338.          ((int) (niqmatrixptr[pos]))) >> 4; 
  339.     coeff += (coeff & 1);
  340.       } else {
  341.     coeff = (((level<<1) + 1) * qscale * 
  342.          ((int) (*(niqmatrixptr+pos)))) >> 4; 
  343.     coeff -= (coeff & 1);
  344.       }
  345.       reconptr[pos] = coeff;
  346.       coeffCount = (coeff!=0);
  347.       
  348.       if (curVidStream->picture.code_type != 4) {
  349.     
  350.     while(1) {
  351.       
  352.       DecodeDCTCoeffNext(run, level);
  353.  
  354.       if (run == END_OF_BLOCK) break;
  355.  
  356.       i = i+run+1;
  357.       DeZigZag(pos,i);
  358.       if (opts&COLLECTING&DCT_INFO) {
  359.         sprintf(scratch, "%d %d, ",pos,level);
  360.         strcat(dctSpecifics,scratch);
  361.       }        
  362.       if (level < 0) {
  363.           coeff = (((level<<1) - 1) * qscale * 
  364.                ((int) (niqmatrixptr[pos]))) >> 4; 
  365.           coeff += (coeff & 1);
  366.       } else {
  367.           coeff = (((level<<1) + 1) * qscale * 
  368.                ((int) (*(niqmatrixptr+pos)))) >> 4; 
  369.           coeff -= (coeff & 1);
  370.       }
  371.       reconptr[pos] = coeff;
  372.       coeffCount++;  /* Used to be if (coeff), but I couldnt see why */
  373.     }
  374.     {
  375.       extern unsigned int *mbCoeffPtr;
  376.       if (COLLECTING) mbCoeffPtr[pos]++;
  377.     }
  378.  
  379.     flush_bits(2);
  380.  
  381.     goto end;
  382.       }
  383.     }
  384.     
  385.   end:
  386.  
  387.     if (coeffCount == 1) j_rev_dct_sparse (reconptr, pos);
  388.     else j_rev_dct(reconptr);
  389.  
  390. #ifdef RISC
  391.     temp_curBits = curBits;
  392.     temp_bitOffset = bitOffset;
  393.     temp_bufLength = bufLength;
  394.     temp_bitBuffer = bitBuffer;
  395. #endif
  396.  
  397.   }
  398.  
  399. #ifdef RISC
  400.   curBits = temp_curBits;
  401.   bitOffset = temp_bitOffset;
  402.   bufLength = temp_bufLength;
  403.   bitBuffer = temp_bitBuffer;
  404. #endif
  405.   return PARSE_OK;
  406. }
  407.     
  408. #undef DCT_recon 
  409. #undef DCT_dc_y_past 
  410. #undef DCT_dc_cr_past 
  411. #undef DCT_dc_cb_past 
  412.  
  413.  
  414. /*
  415.  *--------------------------------------------------------------
  416.  *
  417.  * ParseAwayBlock --
  418.  *
  419.  *    Parses off block values, throwing them away.
  420.  *      Used when not verifying
  421.  *
  422.  * Results:
  423.  *    None.
  424.  *
  425.  * Side effects:
  426.  *      None.
  427.  *
  428.  *--------------------------------------------------------------
  429.  */
  430.  
  431. int
  432. ParseAwayBlock(n)
  433.      int n;
  434. {
  435.   unsigned int diff;
  436.   unsigned int size, run;
  437.   int level;
  438.  
  439.   if (bufLength < 100)
  440.     correct_underflow();
  441.  
  442.   if (curVidStream->mblock.mb_intra) {
  443.  
  444.     /* If the block is a luminance block... */
  445.  
  446.     if (n < 4) {
  447.  
  448.       /* Parse and decode size of first coefficient. */
  449.  
  450.       DecodeDCTDCSizeLum(size);
  451.  
  452.       /* Parse first coefficient. */
  453.  
  454.       if (size != 0) {
  455.     get_bitsn(size, diff);
  456.       }
  457.     }
  458.  
  459.     /* Otherwise, block is chrominance block... */
  460.  
  461.     else {
  462.  
  463.       /* Parse and decode size of first coefficient. */
  464.  
  465.       DecodeDCTDCSizeChrom(size);
  466.  
  467.       /* Parse first coefficient. */
  468.  
  469.       if (size != 0) {
  470.     get_bitsn(size, diff);
  471.       }
  472.     }
  473.   }
  474.  
  475.   /* Otherwise, block is not intracoded... */
  476.  
  477.   else {
  478.  
  479.     /* Decode and set first coefficient. */
  480.  
  481.     DecodeDCTCoeffFirst(run, level);
  482.   }
  483.  
  484.   /* If picture is not D type (i.e. I, P, or B)... */
  485.  
  486.   if (curVidStream->picture.code_type != 4) {
  487.  
  488.     /* While end of macroblock has not been reached... */
  489.  
  490.     while (1) {
  491.  
  492.       /* Get the dct_coeff_next */
  493.  
  494.       DecodeDCTCoeffNext(run, level);
  495.  
  496.       if (run == END_OF_BLOCK) break;
  497.     }
  498.  
  499.     /* End_of_block */
  500.  
  501.     flush_bits(2);
  502.   }
  503.   return PARSE_OK;
  504. }
  505.